#include "SpinnerStepCalculator.h"
#include "TurnAbilityVisitor.h"
#include "ActivateAbilityVisitor.h"
#include "ActivateStep.h"

SpinnerStepCalculator::SpinnerStepCalculator(): activatableObject(0), activatableInterface(0)
{
}

SpinnerStepCalculator::~SpinnerStepCalculator()
{
	Clear();
}

void SpinnerStepCalculator::Clear()
{
	std::list<Step*>::iterator it;

	for(it = steps.begin(); it != steps.end(); ++it)
	{
		delete (*it);
	}

	steps.clear();
}

void SpinnerStepCalculator::SetActivator(GameObject* spinner)
{
	ActivateAbilityVisitor activateVisitor;

	spinner->Accept(activateVisitor);

	if (activateVisitor.FoundAbility())
	{
		activatableObject = spinner;
		activatableInterface = activateVisitor.ActivatableInterface();
	}
}

void SpinnerStepCalculator::SetTurnDirection(const Direction& direction)
{
	turnDirection = direction;
}


void SpinnerStepCalculator::GenerateSteps(Board& board)
{
	Clear();

	if (!activatableObject && !activatableInterface)
		return;

	Cell& cell = board.CellAt(activatableObject);

	const std::list<GameObject*>& cellobjects = cell.GetObjects();
	std::list<GameObject*>::const_iterator it;

	
	for(it = cellobjects.begin(); it != cellobjects.end(); ++it)
	{
		GameObject* object = (*it);

		TurnAbilityVisitor turnVisitor;

		object->Accept(turnVisitor);

		if (turnVisitor.FoundAbility())
		{
			AddStep(object, turnVisitor.TurnableInterface());
		}
	}

	if (steps.size())
	{
		ActivateStep* step = new ActivateStep();

		step->SetObject(activatableObject, activatableInterface);
		steps.push_front(step);
	}
}

void SpinnerStepCalculator::AddStep(GameObject* object, Turnable* turnable)
{
	TurnStep* step = new TurnStep();

	step->SetObject(object, turnable);
	step->SetDirection(turnDirection);

	steps.push_back(step);
}


void SpinnerStepCalculator::Execute()
{
	std::list<Step*>::iterator it;

	for(it = steps.begin(); it != steps.end(); ++it)
	{
		(*it)->Execute();
	}
}


